﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using AzureMLClient;
using AzureMLClient.Contracts;

namespace CmdDemo
{
    public class Program
    {
        private const string RetrainWebServiceId = "2deaba4123ec46b8921120eb8ffa3246";
        private const string ScoringWebServiceId = "7df2a06ad50348d78f0e1cb81f3742ab";

        private const string RetrainEndpointName = "retrain";
        private const string ScoringEndpointName = "prod";

        public static void Main()
        {
            Run().Wait();
        }

        public static async Task Run()
        {
            var client = new Client();

            // upload training data
            var trainingData = Helper.UploadFileToBlob(@"C:\Users\micman\Downloads\Iris Two Class Data.arff");

            // pick retrain endpoint
            var webServices = await client.GetWebServicesAsync();
            var retrainEndpoint = webServices.First(w => w.Id == RetrainWebServiceId).Endpoints.FirstOrDefault(e => e.Name == RetrainEndpointName);

            // retrain endpoint
            var jobId = await retrainEndpoint.SubmitBatch(new BatchRequest()
            {
                Input = trainingData
            });

            // wait until retraining job finishes
            var status = await retrainEndpoint.GetBatchStatus(jobId);
            while (!status.Completed())
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                status = await retrainEndpoint.GetBatchStatus(jobId);
            }

            if (status.StatusCode != BatchScoreStatusCode.Finished)
            {
                throw new Exception(string.Format("Retrainig job {0} returned status:{1}, datails:{2}", jobId, status.StatusCode, status.Details));
            }

            // check out retrained eval
            var result = status.Results[Configurations.EvaluationOutputPortName];
            var eval = result.ToUri();
            Console.WriteLine(string.Format("Evaluation result is at {0}", eval));

            var model = status.Results[Configurations.TrainedModelOutputPortName];

            // pick scoring endpoint
            var scoringEndpoint = webServices.First(w => w.Id == ScoringWebServiceId).Endpoints.FirstOrDefault(e => e.Name == ScoringEndpointName);

            // update scoring endpoint with retrained model
            var updateResult = await scoringEndpoint.UpdateResource(new ResourceLocations() { Resources = new []{ new EndpointResource(){Name = Configurations.ScoringResourceName, Location = model } }});

            if (updateResult)
            {
                Console.WriteLine("Successfully updated scoring endpoint");
            }
            else
            {
                Console.WriteLine("Failed to update scoring endpoint");
            }
        }
    }
}
